<template>
  <!-- 所有的 template下面都要有 div 标注-->
  <div>
    <el-card style="margin: 0 0 10px 0">
      <Catagory
        @c1Change="c1Change"
        @c2Change="c2Change"
        @c3Change="c3Change"
        ref="catagoryRef"
      ></Catagory>
    </el-card>
    <el-card>
      <div v-show="scene == 0">
        <el-button
          type="primary"
          icon="Plus"
          :disabled="addAttrDisable"
          @click="addAttr"
          >添加属性</el-button
        >
        <el-table
          :border="true"
          style="width: 100%; margin-top: 10px"
          :data="tableData"
        >
          <el-table-column
            type="index"
            label="序号"
            :align="'center'"
            width="60"
          />
          <el-table-column
            prop="name"
            label="属性名称"
            :align="'center'"
            width="180"
          />
          <el-table-column prop="address" label="属性值" :align="'center'">
            <template #default="scope">
              <el-tag
                :disable-transitions="true"
                style="margin: 0 10px 0 0"
                v-for="(item, index) in scope.row.valueList"
                :key="item.id"
                type="primary"
                >{{ item.name }}</el-tag
              >
            </template>
          </el-table-column>
          <el-table-column label="操作" :align="'center'" width="180">
            <template #default="scope">
              <el-button
                type="primary"
                @click="handleEdit(scope.$index, scope.row)"
                >编辑</el-button
              >
              <el-popconfirm
                :title="`确认删除${scope.row.name}吗？`"
                placement="left-start"
                @confirm="confirmDeleteAttrName(scope.row.id)"
              >
                <template #reference>
                  <el-button
                    type="danger"
                    @click="handleDelete(scope.$index, scope.row)"
                    >删除</el-button
                  >
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-show="scene == 1">
        <el-form :inline="true">
          <el-form-item label="属性名称">
            <el-input
              v-model="attrNameData.name"
              placeholder="请输入属性名称"
              clearable
              ref="oneref"
            />
          </el-form-item>
        </el-form>
        <el-button
          type="primary"
          icon="Plus"
          :disabled="attrNameData.name == ''"
          @click="addOneValue"
          >添加属性值</el-button
        >
        <el-table
          :data="attrNameData.valueList"
          :border="true"
          style="width: 100%; margin: 10px 0"
        >
          <el-table-column
            label="序号"
            type="index"
            :align="'center'"
            width="60"
          />
          <el-table-column prop="name" label="属性值" :align="'center'">
            <template #default="scope">
              <el-input
                v-if="scope.row.focus"
                v-model="scope.row.name"
                @blur="toggleToSHow(scope.row, scope.$index)"
                :ref="(el: any) => pushInputRefs(el, scope.$index)"
              ></el-input>
              <div v-else @click="toggleToEdit(scope.$index)">
                {{ scope.row.name }}
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="180" :align="'center'">
            <template #default="scope">
              <el-button
                type="primary"
                icon="Delete"
                @click="deleteCurrentAttrValue(scope.$index)"
              />
            </template>
          </el-table-column>
        </el-table>
        <el-button
          type="primary"
          @click="confirmAdd"
          :disabled="attrNameData.name == ''"
          >确定</el-button
        >
        <el-button @click="cancelAdd">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import {
  rqaAttrNameList,
  reqAddAttrName,
  deleteAddAttrName,
} from '@/api/product/attr'
import type { AttrNameData, AttrValueData } from '@/api/product/attr/types'
import { ElMessage } from 'element-plus'
import { fa } from 'element-plus/es/locales.mjs'
import { nextTick, reactive, ref } from 'vue'

const catagoryRef = ref()
const tableData = ref<AttrNameData[]>([])
let addAttrDisable = ref(true)
let scene = ref(0)
// 属性值的待提交数据
let attrNameData = reactive<AttrNameData>({
  name: '',
  attrId: undefined as any,
  valueList: [],
})
// input组件实例，用于调用input组件相关的方法
let inputRefs = ref<any>([])

const c1Change = (value: number) => {
  console.log('c1Change', value)
  tableData.value = []
}
const c2Change = (value: number) => {
  console.log('c2Change', value)
  tableData.value = []
}
const refreshTable = async (c3Id: number) => {
  let { data } = await rqaAttrNameList(c3Id)
  tableData.value = data
}
// 三级分类有值时，“添加属性”才显示出来
const c3Change = (value: number) => {
  console.log('c3Change', value)
  if (value) {
    addAttrDisable.value = false
    // 显示属性值表格
    refreshTable(value)
    // 添加属性值页面的待提交数据
    attrNameData.attrId = value
  } else {
    addAttrDisable.value = true
  }
}
const addAttr = () => {
  scene.value = 1
  // 清空“属性值的待提交数据”中的一些字段
  Object.assign(attrNameData, {
    name: '',
    valueList: [],
  })
  inputRefs.value = []
  // 禁止分类下拉框点击
  catagoryRef.value.disableAll()
}
const handleEdit = (index: any, row: any) => {
  scene.value = 1
  // 清空“属性值的待提交数据”中的一些字段
  Object.assign(attrNameData, JSON.parse(JSON.stringify(row)))
  inputRefs.value = []
  // 禁止分类下拉框点击
  catagoryRef.value.disableAll()
}
const confirmDeleteAttrName = async (id: number) => {
  let response = await deleteAddAttrName(id)
  if (response.code == 200) {
    ElMessage.success('删除属性成功')
  } else {
    ElMessage.error('删除属性失败')
  }
  refreshTable(attrNameData.attrId as any)
  scene.value = 0
  catagoryRef.value.enableAll()
}
const handleDelete = (index: any, row: any) => {
  console.log('handleDelete', index, row)
}
const addOneValue = () => {
  // 添加数据：会触发生成新的一行、会触发dom更新
  attrNameData.valueList.push({ name: '', focus: true })
  // 等下一次dom变更后，执行方法：更新dom为聚焦状态
  nextTick(() => {
    inputRefs.value[inputRefs.value.length - 1].focus()
  })
}
// :ref执行的函数：组件实例新生成时，执行该方法
const pushInputRefs = (el: any, $index: number) => {
  console.log('pushInputRefs', $index)
  inputRefs.value[$index] = el
}
const deleteTableRow = (index: number) => {
  attrNameData.valueList.splice(index, 1)
  inputRefs.value.splice(index, 1)
}
// input失去焦点回调
const toggleToSHow = (row: AttrValueData, $index: number) => {
  console.log('toggleToSHow', $index, row.name)
  let needToBlur = true
  // 非法情况1：没有输入值
  if (row.name.trim() === '') {
    deleteTableRow($index)
    needToBlur = false
    ElMessage.error('属性值不能为空')
  }
  // 非法情况2：值重复
  let repeat = attrNameData.valueList.find((item) => {
    if (row !== item) {
      return row.name === item.name
    }
  })
  if (repeat) {
    deleteTableRow($index)
    needToBlur = false
    ElMessage.error('属性值重复')
  }
  console.log('toggleToSHowneedToBlur', needToBlur)
  if (needToBlur) {
    attrNameData.valueList[$index].focus = false
  }
}
const toggleToEdit = ($index: number) => {
  console.log('toggleToEdit', $index)
  // 变更数据：会触发dom更新
  attrNameData.valueList[$index].focus = true
  // 等下一次dom变更后，执行方法：更新dom为聚焦状态
  nextTick(() => {
    inputRefs.value[$index].focus()
  })
}
const deleteCurrentAttrValue = ($index: number) => {
  deleteTableRow($index)
}
const cancelAdd = () => {
  scene.value = 0
  catagoryRef.value.enableAll()
}
const confirmAdd = async () => {
  console.log('confirmAdd', attrNameData)
  if (!attrNameData.name) {
    ElMessage.error('属性名称不能为空')
  }
  let response = await reqAddAttrName(attrNameData)
  if (response.code == 200) {
    ElMessage.success(attrNameData.id ? '修改属性成功' : '添加属性成功')
  } else {
    ElMessage.error(attrNameData.id ? '修改属性失败' : '添加属性失败')
  }
  refreshTable(attrNameData.attrId as any)
  scene.value = 0
  catagoryRef.value.enableAll()
}
</script>
<script lang="ts">
export default {
  name: 'Attr',
}
</script>

<style scoped></style>
